package com.Express.mvc;

import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 映射器（包含大量网址与方法的对应关系）
 */
public class HandlerMapping {
    private  static Map<String,MVCMapping> data= new HashMap<>();
    //从装有一大堆集合的方法里面获取网址所对应的方法
    public static MVCMapping get(String uri){
        return  data.get(uri);
    }
    //加载配置文件的方法
    public  static  void load(InputStream is){
        Properties ppt =new Properties();
        try {
            ppt.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //获取配置文件中的一个个类
        Collection<Object> values = ppt.values();
        for (Object cla:values) {
            String className=(String) cla;
            Class c= null;
            try {
                //加载配置文件中描述的每一个类
                c = Class.forName(className);
                //创建这个类的对象
                Object obj =c.getConstructor().newInstance();
                //获取这个类的所有方法
                Method [] methods=c.getMethods();
                for (Method m:methods
                     ) {
                    Annotation [] as=m.getAnnotations();
                    if(as!=null)
                    {
                        for (Annotation anno:as
                             ) {
                            if (anno instanceof ResponseBody){
                                //此方法是用于返回字符串给客户端
                                MVCMapping map=new MVCMapping(obj,m,ResponseType.TEXT);
                                //没有处理重复的情况
                                //data.put(((ResponseBody) anno).value(), map);
                               //处理重复的情况
                                Object o=data.put(((ResponseBody) anno).value(), map);
                                if (o!=null){
                                    //存在了重复的 请求地址
                                    throw new RuntimeException("请求地址重复"+((ResponseBody) anno).value());
                                }
                            }
                            else if (anno instanceof ResponseView){
                                //此方法适用于返回界面给客户端
                                MVCMapping map=new MVCMapping(obj,m,ResponseType.VIEW);
                                Object o=  data.put(((ResponseView) anno).value(), map);
                                if (o!=null){
                                    //存在了重复的 请求地址
                                    throw new RuntimeException("请求地址重复"+((ResponseView) anno).value());
                                }
                            }
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }
    /**
     * 映射对象，每一个对象封装了一个方法用于处理请求
     */
    public static class MVCMapping{
        private Object obj;
        private Method method;
        private  ResponseType type;

        public MVCMapping(Object obj, Method method, ResponseType type) {
            this.obj = obj;
            this.method = method;
            this.type = type;
        }

        public MVCMapping() {
        }

        public Object getObj() {
            return obj;
        }

        public void setObj(Object obj) {
            this.obj = obj;
        }

        public Method getMethod() {
            return method;
        }

        public void setMethod(Method method) {
            this.method = method;
        }

        public ResponseType getType() {
            return type;
        }

        public void setType(ResponseType type) {
            this.type = type;
        }
    }
}
